package com.ebt.m.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * 数学计算工具类
 *
 * @author Allen.li
 */
public class MathUtil {
    public static double getMinValueOfDoubleArray(double[] da) {
        double xMin = Double.MAX_VALUE;
        for (int k = 0; k < da.length; k++) {
            if (xMin > da[k]) {
                xMin = da[k];
            }
        }
        return xMin;
    }

    public static double getMaxValueOfDoubleArray(double[] da) {
        double xMax = Double.MIN_VALUE;
        for (int k = 0; k < da.length; k++) {
            if (xMax < da[k]) {
                xMax = da[k];
            }
        }
        return xMax;
    }

    public static int getMinValueOfIntArray(int[] da) {
        int xMin = Integer.MAX_VALUE;
        for (int k = 0; k < da.length; k++) {
            if (xMin > da[k]) {
                xMin = da[k];
            }
        }
        return xMin;
    }

    public static int getMaxValueOfIntArray(int[] da) {
        int xMax = Integer.MIN_VALUE;
        for (int k = 0; k < da.length; k++) {
            if (xMax < da[k]) {
                xMax = da[k];
            }
        }
        return xMax;
    }

    public static double getTwoDecimalDouble(double d) {
        BigDecimal b = new BigDecimal(d);
        return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static float getTwoDecimalFloat(double f) {
        BigDecimal b = new BigDecimal(f);
        return b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    public static String getFormatedDoubleString(double f) {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        df.setMaximumFractionDigits(2);
        df.setGroupingUsed(false);
        return df.format(f);
    }

    /**
     * 格式化货币
     *
     * @param money
     */
    public static String formatMoney(Double money) {
        if (money == null) {
            return "";
        }
        DecimalFormat format = new DecimalFormat("#,###");
        return format.format(money);
    }

    /**
     * 格式化货币-带小数
     *
     * @param money
     */
    public static String formatMoney(Double money, int decimals) {
        if (money == null) {
            return "";
        }
        String fs = "####";
        String ds = ".";
        for (int i = 0; i < decimals; i++) {
            ds += "#";
        }
        fs += ds;
        DecimalFormat format = new DecimalFormat(fs);
        String result = format.format(money);
        if (result.contains(".") && result.lastIndexOf(".") == result.length() - 1) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }

    /**
     * 格式化货币
     * * 处理数字算法
     * {"Method":"ROUND_UP","Decimal":0}//上进位
     * {"Method":"ROUND_DOWN","Decimal":0}//下舍
     * {"Method":"ROUND_HALF_UP","Decimal":0}//四舍五入
     * {"Method":"ROUND_HALF_DOWN","Decimal":0}//五舍六入
     * {"Method":"ROUND_HALF_EVEN","Decimal":0}//银行家算法：四舍六入，5分为两种情况：左面为奇数时，进位；偶数时：舍去
     * 主险：TF_TO4_TO0|0-四舍五入保留4位有效数字后取整1.49995->2
     * 豁免：TF_TO2_TO0|0
     *
     * @param money
     */
    public static String formatMoney(Double money, String method, int decimals) {
        String result = "";
        if (money == null) {
            return result;
        }
        BigDecimal b = new BigDecimal(money + "");
        if (method.contains("TF_TO")) {
            try {
                String temp = method.replace("TF_TO", "").replace("_TO0", "");
                int deci = Integer.valueOf(temp);
                result = b.setScale(deci, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
                b = new BigDecimal(result + "");
                result = b.setScale(0, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
        switch (method) {
            case "ROUND_UP":
                result = b.setScale(decimals, RoundingMode.UP).stripTrailingZeros().toPlainString();
                break;
            case "ROUND_DOWN":
                result = b.setScale(decimals, RoundingMode.DOWN).stripTrailingZeros().toPlainString();
                break;
            case "ROUND_HALF_UP":
                result = b.setScale(decimals, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
                break;
            case "ROUND_HALF_DOWN":
                result = b.setScale(decimals, RoundingMode.HALF_DOWN).stripTrailingZeros().toPlainString();
                break;
            case "ROUND_HALF_EVEN":
                result = b.setScale(decimals, RoundingMode.HALF_EVEN).stripTrailingZeros().toPlainString();
                break;
        }
        return result;
    }

    /**
     * @param d
     * @return
     */
    public static String getPlainDoubleStr(double d) {
        BigDecimal b = new BigDecimal(d + "");
        return b.stripTrailingZeros().toPlainString();
    }

    /**
     * test
     *
     * @param args
     */
    public static void main(String args) {
        String result = formatMoney(1.49995);
        System.out.println(result);
    }

    /**
     * 计算笛卡尔乘积
     *
     * @param arrays 传入数组获取笛卡尔乘积的字符串数组(用_分割)
     * @return
     */
    public static String[] descartes(int[]... arrays) {
        long t1 = System.currentTimeMillis();
        int total = 1;
        for (int i = 0; i < arrays.length; i++) {
            total *= arrays[i].length;
        }
        String[] mysesult = new String[total];
        int now = 1;
        //每个元素每次循环打印个数
        int itemLoopNum = 1;
        //每个元素循环的总次数
        int loopPerItem = 1;
        for (int i = 0; i < arrays.length; i++) {
            int[] temp = arrays[i];
            now = now * temp.length;
            //目标数组的索引值
            int index = 0;
            int currentSize = temp.length;
            itemLoopNum = total / now;
            loopPerItem = total / (itemLoopNum * currentSize);
            int myindex = 0;
            for (int j = 0; j < temp.length; j++) {
                //每个元素循环的总次数
                for (int k = 0; k < loopPerItem; k++) {
                    if (myindex == temp.length) {
                        myindex = 0;
                    }
                    //每个元素每次循环打印个数
                    for (int m = 0; m < itemLoopNum; m++) {
                        mysesult[index] = (mysesult[index] == null ? "" : mysesult[index] + "_") + (temp[myindex]);
                        index++;
                    }
                    myindex++;
                }
            }
        }
        long t2 = System.currentTimeMillis();
        System.out.println("笛卡尔乘积耗时：" + (t2 - t1) + " ms");
        return mysesult;
    }
}
